package batch.process.execute;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import batch.process.BaseBatchProcess;
import batch.process.checker.DueDateChecker;
import batch.process.core.BaseThread;
import batch.process.utils.BatchProcessProperties;
import batch.process.utils.Constant;


public class DueDateReminder extends BaseBatchProcess {

	private static boolean exit = false;
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		CountDownLatch finalizado = null;
		HashMap<String, BaseThread> robos = null;
		File arquivoDeShutdown = null;
		
		try {
			System.out.println(" Initializing due date reminder batch process ...");
			init(args);			
			logger.info("Initializing DueDateReminder ... ", DueDateReminder.class);
		
			// Cria o handle pro arquivo que indica se o sistema deve parar
			arquivoDeShutdown = new File(Constant.MAIN_STOP_FILE_PATH);
			
			// Se o arquivo de shutdown existe enquanto esta subindo, apaga ele
			if (arquivoDeShutdown.isFile()){
				arquivoDeShutdown.delete();
			}
		
			finalizado = new CountDownLatch(1);

			robos = new HashMap<String, BaseThread>();
			robos.put("duedatechecker", new DueDateChecker(finalizado));
				
			for(String nomeRobo: robos.keySet()){
				robos.get(nomeRobo).start();
				logger.info(nomeRobo+" thread initialized. ", DueDateReminder.class);
			}
		
			while (!exit) {								
				if (arquivoDeShutdown.isFile()){
					logger.info("Shutdown file identified. Shutting system down ...",
							DueDateReminder.class);
					exit = true;
				}
				
				// Verifica se as threads ja terminaram
				if (finalizado.getCount() <= 0) {
					exit = true;
				}
				
				if(!exit) {
					Thread.sleep(5000);
				}
			}
		
		} catch (Exception e){
			e.printStackTrace(); 
			logger.error("Error: " + e,DueDateReminder.class);			
		} finally{
			
			// Para todos os robos que ainda esta rodando
			logger.info("Finalizing all active remaining threads ...",
					DueDateReminder.class);
			try {
				if (robos != null) {
					for(String nomeRobo: robos.keySet())
						robos.get(nomeRobo).setFinaliza(true);
				}
			} catch (NullPointerException e) {
				
			} 

			try {
				if (finalizado != null) {
					finalizado.await(10, TimeUnit.SECONDS);
				}
			} catch (InterruptedException e) {
			} 
			
			// Se o arquivo de shutdown existe, apaga ele
			if (arquivoDeShutdown != null && arquivoDeShutdown.isFile()){
				arquivoDeShutdown.delete();
			}
			
			logger.info("System terminated.",DueDateReminder.class);			
		}		
	}
	
	private static void init(String args[]) throws Exception {
		init();
		getParameters(args);
		loadInitialProperties();
	}

	
	private static void loadInitialProperties() throws Exception {
		logger.info("Loading property files ...",BaseBatchProcess.class);	
		
		Set<String> keys = parameters.keySet();
		Iterator<String> iKeys = keys.iterator();
		
		while(iKeys.hasNext()) {
			String key = iKeys.next();
			String path = parameters.get(key);
			
			logger.info("Reading [" + key + "] at " + path + " ... ",BaseBatchProcess.class);
			BatchProcessProperties.load(path);			
		}
		
	}
	
	
}
